#include "AggregateFunctionResult.h"
#include "../../runtime/AutomaticBoxCreatorRegistration.h"

#include <limits>
namespace jm4bbx {
	

	const  outType AggregateFunctionResult::OUT_ARC = outType(0);

	const  columnType AggregateFunctionResult::OUTPUT_COLUMN = columnType(0);

	const  groupType AggregateFunctionResult::OUTPUT_GROUP = groupType(0);

	const char* AggregateFunctionResult::INPUT_COUNT_PARAM_NAME = "inputs";


	class SumResultBox : public AggregateFunctionResult {
	public:
		SumResultBox(const BoxParamPack& p) : AggregateFunctionResult(p) { }

		virtual void initAggregatedValue() { sum_ = 0;}
		virtual void aggregateValue(int value, int aggIndex) { sum_ += value;}
		virtual void outputAggregatedValue() { 
			addOutputData(IntegerKeyRecord(0, sum_)); 
		}
	private:
		int sum_;
	};
	REGISTER_BOX_TO_RUNTIME_BASE(SUM_RESULT_INTEGER, SumResultBox);

	class MinResultBox : public AggregateFunctionResult {
	public:
		MinResultBox(const BoxParamPack& p) : AggregateFunctionResult(p) { }

		virtual void initAggregatedValue() { 
			min_ = std::numeric_limits<int>::max();
		}
		
		virtual void aggregateValue(int value, int aggIndex) { 
			if (value < min_) min_ = value;
		}
		
		virtual void outputAggregatedValue() { 
			addOutputData(IntegerKeyRecord(0, min_));
		}
	private:
		int min_;
	};
	REGISTER_BOX_TO_RUNTIME_BASE(MIN_RESULT_INTEGER, MinResultBox);

	class MaxResultBox : public AggregateFunctionResult {
	public:
		MaxResultBox(const BoxParamPack& p) : AggregateFunctionResult(p) { }

		virtual void initAggregatedValue() { 
			max_ = std::numeric_limits<int>::min();
		}
		
		virtual void aggregateValue(int value, int aggIndex) {
			if (value > max_) max_ = value;
		}

		virtual void outputAggregatedValue() { 
			addOutputData(IntegerKeyRecord(0, max_)); 
		}
	private:
		int max_;
	};
	REGISTER_BOX_TO_RUNTIME_BASE(MAX_RESULT_INTEGER, MaxResultBox);

	class AvgResultBox : public AggregateFunctionResult {
	public:
		AvgResultBox(const BoxParamPack& p) : AggregateFunctionResult(p) { }

		virtual void initAggregatedValue() { sum_ = count_ = 0;}
		virtual void aggregateValue(int value, int aggIndex) { 
			if (aggIndex == 0) {
				sum_ += value;
			}
			else {
				count_ += value;
			}
		}
		virtual void outputAggregatedValue() { 
			addOutputData(IntegerKeyRecord(0, sum_/(double)count_));
		}
	private:
		int sum_;
		int count_;
	};
	REGISTER_BOX_TO_RUNTIME_BASE(AVG_RESULT_INTEGER, AvgResultBox);
} // namespace jm4bbx
